/**
 * @file market_data.cpp
 * @brief 市场数据处理相关实现
 * @details 实现了订单簿(OrderBook)的数据结构和相关操作
 */

#include "market_data/order_book_manager.h"
#include "market_data/market_data_manager.h"
#include "market_data/market_data_types.h"
#include <algorithm>
#include <stdexcept>
#include <spdlog/spdlog.h>
#include <chrono>

namespace hft {

/**
 * @brief 订单簿构造函�?
 * @param symbol 交易品种代码
 */
OrderBook::OrderBook(const std::string& symbol) : symbol_(symbol) {}

/**
 * @brief 更新订单簿中的价格档�?
 * @param level 价格档位信息
 * @param side 买卖方向
 * @details 根据买卖方向更新对应的价格档位，并保持价格排�?
 */
void OrderBook::update(const PriceLevel& level, OrderSide side) {
    auto& levels = (side == OrderSide::BUY) ? bids_ : asks_;
    
    // 查找是否存在相同价格的价格档�?
    auto it = std::find_if(levels.begin(), levels.end(),
        [&level](const PriceLevel& l) { return l.price == level.price; });
    
    if (it != levels.end()) {
        // 如果存在，则更新该价格档�?
        *it = level;
    } else {
        // 如果不存在，则添加新的价格档�?
        levels.push_back(level);
        // 根据买卖方向进行排序
        if (side == OrderSide::BUY) {
            // 买单按价格从高到低排�?
            std::sort(levels.begin(), levels.end(),
                [](const PriceLevel& a, const PriceLevel& b) { return a.price > b.price; });
        } else {
            // 卖单按价格从低到高排�?
            std::sort(levels.begin(), levels.end(),
                [](const PriceLevel& a, const PriceLevel& b) { return a.price < b.price; });
        }
    }
}

/**
 * @brief 从订单簿中移除指定价格的价格档位
 * @param price 要移除的价格
 * @param side 买卖方向
 */
void OrderBook::remove(double price, OrderSide side) {
    auto& levels = (side == OrderSide::BUY) ? bids_ : asks_;
    levels.erase(
        std::remove_if(levels.begin(), levels.end(),
            [price](const PriceLevel& level) { return level.price == price; }),
        levels.end()
    );
}

/**
 * @brief 清空订单�?
 * @details 清空所有买单和卖单
 */
void OrderBook::clear() {
    bids_.clear();
    asks_.clear();
}

/**
 * @brief 获取最优买�?
 * @return 最优买�?
 * @throws std::runtime_error 当订单簿中没有买单时抛出异常
 */
double OrderBook::getBestBid() const {
    if (bids_.empty()) {
        throw std::runtime_error("No bids in order book");
    }
    return bids_.front().price;
}

/**
 * @brief 获取最优卖�?
 * @return 最优卖�?
 * @throws std::runtime_error 当订单簿中没有卖单时抛出异常
 */
double OrderBook::getBestAsk() const {
    if (asks_.empty()) {
        throw std::runtime_error("No asks in order book");
    }
    return asks_.front().price;
}

/**
 * @brief 计算买卖价差
 * @return 买卖价差（最优卖�?- 最优买价）
 * @throws std::runtime_error 当订单簿为空时抛出异�?
 */
double OrderBook::getSpread() const {
    if (bids_.empty() || asks_.empty()) {
        throw std::runtime_error("Cannot calculate spread: empty order book");
    }
    return getBestAsk() - getBestBid();
}

bool MarketDataManager::init(const YAML::Node& config) {
    try {
        config_ = config;
        
        // 创建数据提供�?
        const auto& provider_config = config["trading"]["market_data"]["provider"];
        std::string provider_type = provider_config["type"].as<std::string>();
        
        if (provider_type == "simulation") {
            // TODO: 创建模拟数据提供�?
            spdlog::info("Using simulation market data provider");
        } else if (provider_type == "ctp") {
            // TODO: 创建CTP数据提供�?
            spdlog::info("Using CTP market data provider");
        } else {
            spdlog::error("Unknown market data provider type: {}", provider_type);
            return false;
        }

        // 初始化数据提供�?
        if (!provider_->init(config)) {
            spdlog::error("Failed to initialize market data provider");
            return false;
        }

        spdlog::info("Market data manager initialized successfully");
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize market data manager: {}", e.what());
        return false;
    }
}

bool MarketDataManager::start() {
    if (running_) {
        spdlog::warn("Market data manager is already running");
        return true;
    }

    try {
        // 启动数据提供�?
        if (!provider_->start()) {
            spdlog::error("Failed to start market data provider");
            return false;
        }

        running_ = true;
        spdlog::info("Market data manager started successfully");
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to start market data manager: {}", e.what());
        return false;
    }
}

void MarketDataManager::stop() {
    if (!running_) {
        spdlog::warn("Market data manager is not running");
        return;
    }

    try {
        // 停止数据提供�?
        provider_->stop();
        running_ = false;
        spdlog::info("Market data manager stopped successfully");
    } catch (const std::exception& e) {
        spdlog::error("Failed to stop market data manager: {}", e.what());
    }
}

bool MarketDataManager::subscribe(const std::string& symbol, 
                                std::shared_ptr<MarketDataSubscriber> subscriber) {
    if (!running_) {
        spdlog::error("Market data manager is not running");
        return false;
    }

    try {
        std::lock_guard<std::mutex> lock(mutex_);

        // 订阅数据提供�?
        if (!provider_->subscribe(symbol)) {
            spdlog::error("Failed to subscribe symbol: {}", symbol);
            return false;
        }

        // 添加订阅�?
        subscribers_[symbol].push_back(subscriber);
        spdlog::info("Subscribed to symbol: {}", symbol);
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to subscribe symbol {}: {}", symbol, e.what());
        return false;
    }
}

bool MarketDataManager::unsubscribe(const std::string& symbol, 
                                  std::shared_ptr<MarketDataSubscriber> subscriber) {
    if (!running_) {
        spdlog::error("Market data manager is not running");
        return false;
    }

    try {
        std::lock_guard<std::mutex> lock(mutex_);

        // 查找订阅者列�?
        auto it = subscribers_.find(symbol);
        if (it == subscribers_.end()) {
            spdlog::warn("No subscribers found for symbol: {}", symbol);
            return false;
        }

        // 移除订阅�?
        auto& subscribers = it->second;
        auto sub_it = std::find(subscribers.begin(), subscribers.end(), subscriber);
        if (sub_it == subscribers.end()) {
            spdlog::warn("Subscriber not found for symbol: {}", symbol);
            return false;
        }

        subscribers.erase(sub_it);

        // 如果没有订阅者了，取消订阅数据提供�?
        if (subscribers.empty()) {
            if (!provider_->unsubscribe(symbol)) {
                spdlog::error("Failed to unsubscribe symbol: {}", symbol);
                return false;
            }
            subscribers_.erase(it);
        }

        spdlog::info("Unsubscribed from symbol: {}", symbol);
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to unsubscribe symbol {}: {}", symbol, e.what());
        return false;
    }
}

MarketDataMessage MarketDataManager::getLatestMarketData(const std::string& symbol) const {
    std::lock_guard<std::mutex> lock(mutex_);
    auto it = latest_data_.find(symbol);
    if (it == latest_data_.end()) {
        return MarketDataMessage{};
    }
    return it->second;
}

std::vector<MarketDataMessage> MarketDataManager::getHistoricalMarketData(
    const std::string& symbol,
    const std::chrono::system_clock::time_point& start_time,
    const std::chrono::system_clock::time_point& end_time) const {
    
    std::lock_guard<std::mutex> lock(mutex_);
    std::vector<MarketDataMessage> result;

    auto it = historical_data_.find(symbol);
    if (it == historical_data_.end()) {
        return result;
    }

    const auto& data_queue = it->second;
    std::queue<MarketDataMessage> temp_queue = data_queue;

    while (!temp_queue.empty()) {
        const auto& data = temp_queue.front();
        if (data.timestamp >= start_time && data.timestamp <= end_time) {
            result.push_back(data);
        }
        temp_queue.pop();
    }

    return result;
}

void MarketDataManager::processMarketData(const MarketDataMessage& data) {
    std::lock_guard<std::mutex> lock(mutex_);

    // 更新最新行�?
    latest_data_[data.symbol] = data;

    // 更新历史行情
    auto& historical_queue = historical_data_[data.symbol];
    historical_queue.push(data);
    if (historical_queue.size() > MAX_HISTORICAL_DATA_SIZE) {
        historical_queue.pop();
    }

    // 通知订阅�?
    auto it = subscribers_.find(data.symbol);
    if (it != subscribers_.end()) {
        for (const auto& subscriber : it->second) {
            try {
                subscriber->onMarketData(data);
            } catch (const std::exception& e) {
                spdlog::error("Error in subscriber callback: {}", e.what());
            }
        }
    }
}

// OrderBookManager实现
OrderBookManager::OrderBookManager(const Symbol& symbol) {
    order_book_.symbol = symbol;
    order_book_.timestamp = std::chrono::system_clock::now();
    spdlog::info("Created OrderBook for symbol: {}", symbol);
}

void OrderBookManager::update(const std::pair<Price, Volume>& level, OrderDirection direction) {
    spdlog::debug("Updating OrderBook for symbol: {}, direction: {}, price: {}, volume: {}", 
        order_book_.symbol, 
        direction == OrderDirection::BUY ? "BUY" : "SELL",
        level.first,
        level.second);
    auto& levels = (direction == OrderDirection::BUY) ? order_book_.bids : order_book_.asks;
    
    // 查找是否已存在该价格档位
    auto it = std::find_if(levels.begin(), levels.end(),
        [&level](const auto& existing) { return existing.first == level.first; });
    
    if (it != levels.end()) {
        // 更新现有档位
        it->second = level.second;
        if (level.second == 0) {
            // 如果数量为0，移除该档位
            levels.erase(it);
        }
    } else if (level.second > 0) {
        // 添加新档位
        levels.push_back(level);
        // 按价格排序：买盘降序，卖盘升序
        if (direction == OrderDirection::BUY) {
            std::sort(levels.begin(), levels.end(),
                [](const auto& a, const auto& b) { return a.first > b.first; });
        } else {
            std::sort(levels.begin(), levels.end(),
                [](const auto& a, const auto& b) { return a.first < b.first; });
        }
    }
    
    order_book_.timestamp = std::chrono::system_clock::now();
}

void OrderBookManager::remove(Price price, OrderDirection direction) {
    spdlog::debug("Removing price level from OrderBook for symbol: {}, direction: {}, price: {}", 
        order_book_.symbol, 
        direction == OrderDirection::BUY ? "BUY" : "SELL",
        price);
    
    auto& levels = (direction == OrderDirection::BUY) ? order_book_.bids : order_book_.asks;
    
    // 查找并移除指定价格档位
    auto it = std::find_if(levels.begin(), levels.end(),
        [price](const auto& level) { return level.first == price; });
    
    if (it != levels.end()) {
        levels.erase(it);
        spdlog::debug("Price level removed successfully");
    } else {
        spdlog::debug("Price level not found");
    }
    
    order_book_.timestamp = std::chrono::system_clock::now();
}

void OrderBookManager::clear() {
    spdlog::info("Clearing OrderBook for symbol: {}", order_book_.symbol);
    
    order_book_.bids.clear();
    order_book_.asks.clear();
    order_book_.timestamp = std::chrono::system_clock::now();
}

Price OrderBookManager::getBestBid() const {
    if (!order_book_.bids.empty()) {
        Price best_bid = order_book_.bids.front().first;
        spdlog::debug("Best bid for symbol {}: {}", order_book_.symbol, best_bid);
        return best_bid;
    }
    spdlog::debug("No bids available for symbol {}", order_book_.symbol);
    return 0.0; // 当没有买单时返回0
}

Price OrderBookManager::getBestAsk() const {
    if (!order_book_.asks.empty()) {
        Price best_ask = order_book_.asks.front().first;
        spdlog::debug("Best ask for symbol {}: {}", order_book_.symbol, best_ask);
        return best_ask;
    }
    spdlog::debug("No asks available for symbol {}", order_book_.symbol);
    return 0.0; // 当没有卖单时返回0
}

Price OrderBookManager::getSpread() const {
    if (!order_book_.bids.empty() && !order_book_.asks.empty()) {
        Price spread = order_book_.asks.front().first - order_book_.bids.front().first;
        spdlog::debug("Spread for symbol {}: {}", order_book_.symbol, spread);
        return spread;
    }
    spdlog::debug("Cannot calculate spread for symbol {}: empty order book", order_book_.symbol);
    return 0.0; // 当无法计算价差时返回0
}

const OrderBook& OrderBookManager::getOrderBook() const {
    spdlog::debug("Getting OrderBook for symbol {}, bids: {}, asks: {}", 
        order_book_.symbol, 
        order_book_.bids.size(), 
        order_book_.asks.size());
    return order_book_;
}

// MarketDataManager实现
bool MarketDataManager::init(const std::string& config) {
    // 解析配置文件，初始化市场数据管理器
    // 这里简单返回true，实际实现可能需要解析JSON配置等
    return true;
}

void MarketDataManager::addProvider(std::shared_ptr<MarketDataProvider> provider) {
    if (provider) {
        providers_.push_back(provider);
        
        // 如果已经注册了回调函数，则将其注册到新的提供者
        if (callback_) {
            provider->registerCallback(callback_);
        }
    }
}

bool MarketDataManager::subscribe(const Symbol& symbol) {
    bool success = true;
    
    // 遍历所有提供者，订阅行情
    for (auto& provider : providers_) {
        if (!provider->subscribe(symbol)) {
            success = false;
        }
    }
    
    return success;
}

bool MarketDataManager::unsubscribe(const Symbol& symbol) {
    bool success = true;
    
    // 遍历所有提供者，取消订阅
    for (auto& provider : providers_) {
        if (!provider->unsubscribe(symbol)) {
            success = false;
        }
    }
    
    return success;
}

void MarketDataManager::registerCallback(std::function<void(const MarketData&)> callback) {
    callback_ = callback;
    
    // 将回调函数注册到所有提供者
    for (auto& provider : providers_) {
        provider->registerCallback(callback);
    }
}

MarketData MarketDataManager::getLatestData(const Symbol& symbol) {
    // 如果有多个提供者，可以选择第一个有效的数据或者合并数据
    // 这里简单地返回第一个提供者的数据
    if (!providers_.empty()) {
        spdlog::debug("Getting latest data for symbol {} from provider", symbol);
        return providers_[0]->getLatestData(symbol);
    }
    
    // 如果没有提供者，返回空的MarketData
    spdlog::warn("No market data providers available for symbol {}", symbol);
    MarketData empty_data;
    empty_data.symbol = symbol;
    empty_data.timestamp = std::chrono::system_clock::now();
    return empty_data;
}

std::vector<MarketData> MarketDataManager::getHistoricalData(
    const Symbol& symbol,
    const Timestamp& start_time,
    const Timestamp& end_time) {
    
    // 如果有多个提供者，可以选择第一个有效的数据或者合并数据
    // 这里简单地返回第一个提供者的数据
    if (!providers_.empty()) {
        spdlog::debug("Getting historical data for symbol {} from {} to {}", 
            symbol, 
            std::chrono::system_clock::to_time_t(start_time),
            std::chrono::system_clock::to_time_t(end_time));
        
        auto data = providers_[0]->getHistoricalData(symbol, start_time, end_time);
        spdlog::debug("Retrieved {} historical records for symbol {}", data.size(), symbol);
        return data;
    }
    
    // 如果没有提供者，返回空列表
    spdlog::warn("No market data providers available for historical data of symbol {}", symbol);
    return {};
}

} // namespace hft 